<?php
/**
 * #Celebrate Shieh
 *             ,%%%%%%%%,
 *           ,%%/\%%%%/\%%
 *          ,%%%\c "" J/%%%
 * %.       %%%%/ o  o \%%%
 * `%%.     %%%%    _  |%%%
 *  `%%     `%%%%(__Y__)%%'
 *  //       ;%%%%`\-/%%%'
 * ((       /  `%%%%%%%'
 *  \\    .'          |
 *   \\  /       \  | |
 *    \\/         ) | |
 *     \         /_ | |__
 *     (___________))))))) 攻城湿
 *
 *        _       _
 * __   _(_)_   _(_) __ _ _ __
 * \ \ / / \ \ / / |/ _` |'_ \
 *  \ V /| |\ V /| | (_| | | | |
 *   \_/ |_| \_/ |_|\__,_|_| |_|
 */

namespace App\Services;

use app\Libs\Zip\Zip;
use App\Models\Expansion\Delete;
use App\Models\Expansion\Globe;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class GlobeService
{
    use Service;

    /**
     * 数据库备份首页
     *
     * @param Request $request
     *
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
     */
    public function GlobeIndexService( $request )
    {
        $where  = function ( $query ) use ( $request ) {
            if ( $request->filled('name') and $request->input('name') != '' ) $query->where('title', 'like', "%" . $request->input('name') . "%");
        };
        $select = [ 'id', 'uid', 'title', 'url', 'size', 'created_at', 'file_url' ];
        $with   = [
            'user' => function ( $query ) {
                $query->select('id', 'name');
            },
        ];
        $globe  = Globe::PaginateModel($where, $with, $select);
        $globe->appends([ 'name' => $request->input('name') ])->render();//添加到request
        return $globe;
    }

    /**
     * 备份数据库
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function GlobeCreateService()
    {
        $default     = config('database.default');
        $DB_HOST     = config("database.connections.$default.host");
        $DB_DATABASE = config("database.connections.$default.database"); //从配置文件中获取数据库信息
        $DB_USERNAME = config("database.connections.$default.username");
        $DB_PASSWORD = config("database.connections.$default.password");
        $name        = $DB_DATABASE . "_" . date("Y-m-d_H-i-s") . ".sql";
        $disk        = $this->getStorage('globe');
        $dumpName    = $disk->fileUrl('/' . $name);
        $command     = config('page.globe_url') . "mysqldump --add-drop-table --host=$DB_HOST --user=$DB_USERNAME ";
        if ( $DB_PASSWORD ) $command .= "--password=" . $DB_PASSWORD . " ";
        $command .= $DB_DATABASE;
        $command .= " > " . $dumpName;//拼接命令
        system($command);//执行外部命令
        $data[ 'title' ] = $name;
        $data[ 'uid' ]   = Auth::id();
        $data[ 'url' ]   = $disk->url($name);;
        $data[ 'size' ]     = maxsize(filesize($dumpName));//计算大小
        $data[ 'file_url' ] = $dumpName;
        Globe::CreateModel($data);
        return data();
    }

    /**
     * 批量下载备份数据库
     *
     * @param Request $request
     *
     * @return \Illuminate\Http\RedirectResponse
     */
    public function GlobeStoreService( $request )
    {
        $disk  = $this->getStorage('storage');
        $error = $this->getErrorCode();
        if ( ! is_dir(storage_path() . '/download') ) @mkdir(storage_path() . '/download', 0777, TRUE);
        $reduce_path = 'download/' . md5(time()) . '.zip';
        $id          = explode(',', $request->input('id'));
        $arr         = NULL;
        foreach ( $id as $key => $value ) {
            $title       = '/globe/' . Globe::ValueModel($value, 'title');
            $arr[ $key ] = file_exists(storage_path() . $title) ? storage_path() . $title : FALSE;
            if ( ! $arr[ $key ] ) return back()->with('error', $error::message(1016));
        }
        ( new Zip() )->createZip(storage_path() . '/' . $reduce_path, $arr);//创建压缩包
        $true = $disk->exists($reduce_path);//获取文件
        if ( ! $true ) return back()->with('error', $error::message(1016));
        $data[ 'name' ] = $reduce_path;
        $data[ 'uid' ]  = Auth::id();
        $data[ 'size' ] = maxsize($disk->size($reduce_path));//计算大小
        Delete::CreateModel($data);//添加到删除表，定时删除
        return $disk->download($reduce_path);//下载压缩包
    }

    /**
     * 数据库单个文件下载
     *
     * @param $id
     *
     * @return \Illuminate\Http\RedirectResponse
     */
    public function GlobeEditService( $id )
    {
        $disk  = $this->getStorage('storage');
        $title = 'globe/' . Globe::ValueModel($id, 'title');
        $true  = $disk->exists($title);//获取文件
        if ( ! $true ) return back()->with('error', $this->getErrorCode()::message(1016));
        return $disk->download($title);//下载文件
    }

    /**
     * 删除单个备份数据库文件
     *
     * @param $id
     *
     * @return \Illuminate\Http\RedirectResponse
     */
    public function GlobeDestroyService( $id )
    {
        $disk = $this->getStorage('storage');
        $name = Globe::FindModel($id, [ 'id', 'title' ]);
        $t    = Globe::DestroyModel($id);
        if ( $t ) {
            $true = $disk->exists('globe/' . $name->title);
            if ( $true ) $disk->delete('globe/' . $name->title);//删除文件
            errorStorage('globe', '"文件夹名称" : ' . $name->title . ' "文件路径" : ' . 'globe' . ' "文件" : globe/' . $name->title, '删除备份文件成功', $true ? 'success' : 'info', $true ? '删除备份文件' : '文件不存在或已删除');
        }
        return back()->with('success', $this->getErrorCode()::message(204));
    }

    /**
     * 批量删除数据库备份文件
     *
     * @param Request $request
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function GlobeDeleteService( $request )
    {
        $disk = $this->getStorage('storage');
        foreach ( $request->input('id') as $value ) {
            $name = Globe::FindModel($value, [ 'id', 'title' ]);
            $t    = Globe::DestroyModel($value);
            if ( $t ) {
                $true = $disk->exists('globe/' . $name->title);
                if ( $true ) $disk->delete('globe/' . $name->title);//删除文件
                $success[ '文件夹名称' ] = $name->title;
                $success[ '文件路径' ]  = 'globe';
                $success[ '文件' ]    = 'globe/' . $name->title;
                errorStorage('globe', $success, '删除备份文件成功', $true ? 'success' : 'info', $true ? '删除备份文件' : '文件不存在或已删除');
            }
        }
        return data();
    }
}
